home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / allocwg.com / REALLOC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-11-10  |  6.8 KB  |  209 lines

  1. #ifndef MSC
  2.  
  3.     /*  Non-MSC Version  */
  4.  
  5. #if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
  6.  
  7.     /*  NOTE:  These procedures should only be used for
  8.                large data model programs (i.e., Compact, Large, Huge) */
  9.  
  10. #include <stddef.h>
  11. #include <stdlib.h>
  12. #include "alloc.h"
  13.  
  14. extern  ATABLE  AllocationTable [] ; /* Provide storage for block pointers */
  15. extern  SUNIT   TABLESIZE          ; /* Maximum allocation table size      */
  16. extern  SUNIT   MBSize             ; /* Default allocation block size      */
  17. extern  SUNIT   NEntry             ; /* Number of table entries            */
  18.  
  19. void *realloc ( ap, nbytes )
  20.  
  21.    void        *ap     ;      /*  Pointer to block to be reallocated  */
  22.    size_t       nbytes ;      /*  New size of block                   */
  23.  
  24. /*
  25.          +---------------------------------------+
  26.          |                                       |  
  27.          |  Reallocate block procedure           |  
  28.          |                                       |  
  29.          +---------------------------------------+
  30. */
  31.  
  32. {
  33.    HEADER *Header             ;
  34.    HEADER *LHeader            ;
  35.    HEADER *CheckBlock ()      ;
  36.    HEADER *AllocateBlock ()   ;
  37.    SUNIT  *bptr               ;
  38.    SUNIT  *nptr               ;
  39.    SUNIT  *tptr               ;
  40.    SUNIT  *FindBlock ()       ;
  41.    SUNIT   offset             ;
  42.    SUNIT   noffset            ;
  43.    SUNIT   bsize              ;
  44.    SUNIT   nsize              ;
  45.    SUNIT   allocsize          ;
  46.    void    CollapseBlocks  () ;
  47.    void    FreeEmptyBlocks () ;
  48.    void    NormalizeMBSize () ;
  49.    void    free            () ;
  50.    int     i                  ;
  51.  
  52.       /*  Check pointer passed is O.K.  */
  53.  
  54.    if ((Header = CheckBlock ( ap, &offset )) == NULL )
  55.       return ( NULL ) ;
  56.  
  57.       /*  If block was previously free'ed, reallocate it  */
  58.  
  59.    bptr  = (SUNIT *) ap - 1 ;
  60.    bsize = *bptr & ~FREE    ;
  61.    *bptr = bsize ;
  62.  
  63.       /*  Check for 'virtual' free   */
  64.  
  65.    if ( nbytes == 0 ) {
  66.       free ( ap ) ;
  67.       return ( NULL ) ;
  68.    } ;
  69.  
  70.       /*  Calculate number of bytes needed.     */
  71.  
  72.    allocsize = SSIZE * (( nbytes - 1 ) / SSIZE  + 1 ) ;
  73.    if ( allocsize > MAXALLOC )
  74.       return ( NULL ) ;
  75.  
  76.       /*  Check if there is room in a lower level block  */
  77.  
  78.    for ( i = 0; i < NEntry ; i++ ) {
  79.       if ( AllocationTable [i].Header == Header )
  80.          break ;
  81.       CollapseFreeBlocks ( AllocationTable [i].Header ) ;
  82.       if ((nptr = FindBlock (AllocationTable [i].Header,allocsize)) != NULL){
  83.          memcpy ( (char *) nptr, (char *) (bptr+1), min (bsize,allocsize)) ;
  84.          *bptr |= FREE ;
  85.          Header->Collapsed = FALSE ;
  86.          CollapseFreeBlocks ( Header ) ;
  87.          FreeEmptyBlocks ( Header ) ;
  88.          return ( (void *) nptr ) ;
  89.       } ;
  90.    } ;
  91.  
  92.       /*  Check previous allocation in this block to see if enough room  */
  93.  
  94.    CollapseFreeBlocks ( Header ) ;
  95.    noffset = HSIZE ;
  96.    while ( noffset < offset ) {
  97.       nptr    = (SUNIT *) Header + noffset/SSIZE ;
  98.       nsize   = *nptr & ~FREE ;
  99.       if ( (*nptr & FREE) ) {
  100.          if ( (nsize                   ) >= allocsize ||
  101.              ((noffset + nsize + SSIZE ) == offset &&
  102.               (nsize   + bsize + SSIZE ) >= allocsize )) {
  103.             *nptr    = allocsize ;
  104.             memcpy ( (char *) (nptr + 1), (char *) (bptr+1), 
  105.                       min ( bsize, allocsize ) ) ;
  106.             tptr     = nptr ;
  107.             noffset += allocsize + SSIZE ;
  108.             nptr     = (SUNIT *) Header + noffset/SSIZE ;
  109.             if ( nsize >= allocsize ) {
  110.                *bptr |= FREE ;
  111.                if ( nsize > allocsize )
  112.                   *nptr    = (nsize - allocsize - SSIZE) | FREE ;
  113.             }
  114.             else if ( nsize + bsize + SSIZE > allocsize )
  115.                *nptr    = (bsize + nsize - allocsize) | FREE ;
  116.             Header->Collapsed = FALSE ;
  117.             return ( (void *) (tptr+1) ) ;
  118.          } ;
  119.       } ;
  120.       noffset += nsize+SSIZE  ;
  121.    } ;
  122.  
  123.       /*  Not enough space below so check current allocation  */
  124.  
  125.    if ( allocsize == bsize )
  126.       return ( ap ) ;
  127.    if ( allocsize < bsize ) {
  128.       *bptr   = allocsize ;
  129.       offset += allocsize+SSIZE ;
  130.       *((SUNIT *)Header+offset/SSIZE) = (bsize - allocsize - SSIZE) | FREE ;
  131.       Header->Collapsed = FALSE ;
  132.       return ( ap ) ;
  133.    } ;
  134.  
  135.       /*  Check next allocation to see if free and if enough total room  */
  136.  
  137.    noffset = offset + bsize + SSIZE ;
  138.    if ( noffset < Header->BytesUsed ) {
  139.       nptr  = (SUNIT *) Header + noffset/SSIZE ;
  140.       nsize = *nptr & ~FREE ;
  141.       if ( (*nptr & FREE) && (nsize + bsize + SSIZE) >= allocsize ) {
  142.          *bptr   = allocsize ;
  143.          if ( nsize + bsize + SSIZE > allocsize ) {
  144.             noffset = offset + allocsize + SSIZE ;
  145.             nptr    = (SUNIT *) Header + noffset/SSIZE ;
  146.             *nptr   = (bsize + nsize - allocsize) | FREE ;
  147.             Header->Collapsed = FALSE ;
  148.          } ;
  149.          return ( ap ) ;
  150.       } ;
  151.    } ;
  152.  
  153.       /*  Check if there is room in this or higher level block  */
  154.  
  155.    for (  ; i < NEntry ; i++ ) {
  156.       CollapseFreeBlocks ( AllocationTable [i].Header ) ;
  157.       if ((nptr = FindBlock (AllocationTable [i].Header,allocsize)) != NULL){
  158.          memcpy ( (char *) nptr, (char *) (bptr+1), bsize ) ;
  159.          *bptr |= FREE ;
  160.          Header->Collapsed = FALSE ;
  161.          return ( (void *) nptr ) ;
  162.       } ;
  163.    } ;
  164.  
  165.       /*  Normalize MBSize                   */
  166.  
  167.    NormalizeMBSize () ;
  168.  
  169.       /*  Check if we can expand this block  */
  170.  
  171.    if ( Header == AllocationTable [NEntry-1].Header   && 
  172.         offset + bsize + SSIZE >= Header->BytesUsed      ) 
  173.       *bptr |= FREE ;
  174.    LHeader = AllocationTable [NEntry-1].Header ;
  175.    if ( ExpandBlock ( LHeader, allocsize ) ) {
  176.       AllocationTable [NEntry-1].Size = LHeader->BytesUsed ;
  177.       if ((nptr=FindBlock ( LHeader, allocsize ) ) != NULL ) {
  178.          if ( nptr != (bptr+1) ) {
  179.             memcpy ( (char *) nptr, (char *) (bptr+1), bsize ) ;
  180.             *bptr |=  FREE ;
  181.          }
  182.          else
  183.             *bptr &= ~FREE ;
  184.          Header->Collapsed = FALSE ;
  185.          return ( (void *) nptr ) ;
  186.       } ;
  187.    }
  188.    else
  189.       *bptr &= ~FREE ;
  190.  
  191.       /*  Allocate new block and free space in old block   */
  192.       
  193.    if ( NEntry == TABLESIZE )
  194.       return ( NULL ) ;
  195.    nsize  = MBSize * (( allocsize + HSIZE + SSIZE - 1 ) / MBSize + 1 ) ;
  196.    if ((AllocationTable [NEntry].Header = AllocateBlock (nsize)) == NULL )
  197.       return ( NULL ) ;
  198.    *bptr |= FREE ;
  199.    Header->Collapsed = FALSE ;
  200.  
  201.    Header = AllocationTable [NEntry].Header ;
  202.    AllocationTable [NEntry++].Size = Header->BytesUsed ;
  203.    nptr   = FindBlock ( Header, allocsize ) ;
  204.    memcpy ( (char *) nptr, (char *) (bptr+1), bsize ) ;
  205.    return ( (void *) nptr ) ;
  206. }                             
  207. #endif
  208. #endif
  209.